package com.huiyin.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Xml;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;

import com.huiyin.R;
import com.huiyin.UIHelper;
import com.huiyin.api.URLs;
import com.huiyin.dialog.DownloadDialog;
import com.huiyin.dialog.DownloadDialog.MyCancelClickListener;
import com.huiyin.dialog.UpdateConfirmDialog;
import com.huiyin.dialog.UpdateConfirmDialog.DialogClickListener;

/**
 * @author coolszy
 * @date 2012-4-26
 * @blog http://blog.92coding.com
 */

public class UpdateWebManager {
	private static final String TAG = "UpdateWebManager";

	/* 下载中 */
	private static final int DOWNLOAD = 1;
	/* 下载结束 */
	private static final int DOWNLOAD_FINISH = 2;
	/* 下载失败 */
	private static final int DOWNLOAD_FAIL = 3;
	/* 解压完成 */
	private static final int Ectract_FINISH = 4;
	/* 解压失败 */
	private static final int Ectract_FAIL = 5;
	/* 下载保存路径 */
	private String mSavePath;
	private String mFileName;
	/* 记录进度条数量 */
	private int progress;
	/* 是否取消更新 */
	private boolean cancelUpdate = false;

	private Context mContext;
	/* 更新进度条 */
	private ProgressBar mProgress;
	private TextView tv_pro;

	private String basePath;// 存储的基础路径

	private DownloadDialog downloadProgress;

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			// 正在下载
			case DOWNLOAD:
				// if(mNotification==null) break;
				// // 更新进度
				// RemoteViews contentView = mNotification.contentView;
				// contentView.setTextViewText(R.id.rate, progress + "%");
				// contentView.setProgressBar(R.id.progress, 100, progress,
				// false);
				// if(mNotificationManager!=null) {
				// mNotificationManager.notify(NOTIFY_ID, mNotification);
				// }
				String pro = msg.obj.toString();
				tv_pro.setText("正在下载（" + pro + "）");
				// 设置进度条位置
				mProgress.setProgress(progress);
				break;
			case DOWNLOAD_FINISH:
				// // 下载完毕后变换通知形式
				// mNotification.flags = Notification.FLAG_AUTO_CANCEL;
				// mNotification.contentView = null;
				//
				// File zipfile = new File(mSavePath, mFileName);
				// if (!zipfile.exists()) {
				// return;
				// }
				// Intent i = new Intent(Intent.ACTION_VIEW);
				// PendingIntent contentIntent =
				// PendingIntent.getActivity(mContext, 0, i,
				// PendingIntent.FLAG_ONE_SHOT);
				// mNotification.setLatestEventInfo(mContext, "下载完成", "文件已下载完毕",
				// contentIntent);
				// if(mNotificationManager!=null) {
				// mNotificationManager.notify(NOTIFY_ID, mNotification);
				// }

				tv_pro.setText("正在解压资源");
				mProgress.setIndeterminate(true);
				new EctractTherad().start();
				break;
			case DOWNLOAD_FAIL:
				downloadProgress.dismiss();
				UIHelper.showToast("更新资源异常！");
				break;
			case Ectract_FINISH:
				downloadProgress.dismiss();
				break;
			case Ectract_FAIL:
				downloadProgress.dismiss();
				UIHelper.showToast("解压资源异常！");
				break;
			default:
				break;
			}
		};
	};

	private String downUrl;

	public UpdateWebManager(Context context, String fileName, String downUrl) {
		this.mContext = context;
		mFileName = fileName;

		this.downUrl = URLs.PC_SERVER_URL + downUrl;
	}

	/**
	 * 检测软件更新
	 */
	public boolean checkUpdate(int serviceCode, String content) {
		if (isUpdate(serviceCode)) {
//			// 显示提示对话框
//			showNoticeDialog(content);
			showDownloadDialog();
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 检查软件是否有更新版本
	 * 
	 * @return
	 */
	private boolean isUpdate(int serviceCode) {
		// 获取当前软件版本
		int versionCode = getVersionCode(mContext);
		LogUtil.d(TAG, "isUpdate : serviceCode = " + serviceCode + "  versionCode = " + versionCode);
		// 版本判断
		if (serviceCode > versionCode) {
			return true;
		}
		return false;
	}

	/**
	 * 获取软件版本号
	 * 
	 * @param context
	 * @return
	 */
	private int getVersionCode(Context context) {
		int versionCode = -1;
		FileInputStream is;
		try {
			File file = new File(Environment.getExternalStorageDirectory()
					.getPath() + "/huiyinlehu/www/version.xml");
			// is = context.getResources().getAssets().open("www/version.xml");
			is = new FileInputStream(file);
			// 由android.util.Xml创建一个XmlPullParser实例
			XmlPullParser parser = Xml.newPullParser();
			// 设置输入流 并指明编码方式
			parser.setInput(is, "UTF-8");
			// 产生第一个事件
			int eventType = parser.getEventType();

			while (eventType != XmlPullParser.END_DOCUMENT) {

				switch (eventType) {
				// 判断当前事件是否为文档开始事件
				case XmlPullParser.START_DOCUMENT:

					break;

				// 判断当前事件是否为标签元素开始事件
				case XmlPullParser.START_TAG:

					if (parser.getName().equals("versionCode")) { // 判断开始标签元素是否是book
						parser.next();
						versionCode = Integer.parseInt(parser.getText());
					}
					break;

				// 判断当前事件是否为标签元素结束事件
				case XmlPullParser.END_TAG:

					break;
				}
				// 进入下一个元素并触发相应事件
				eventType = parser.next();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			e.printStackTrace();
		}
		return versionCode;
	}

	/**
	 * 显示软件更新对话框
	 */
	private void showNoticeDialog(String content) {
		// 构造对话框
		UpdateConfirmDialog dialog = new UpdateConfirmDialog(mContext);
		dialog.setCustomTitle("发现新版本");
		dialog.setUpdateContent(content);
		dialog.setConfirm("立即下载");
		dialog.setCancel("稍后更新");
		dialog.setCanceledOnTouchOutside(false);
		dialog.setClickListener(new DialogClickListener() {
			@Override
			public void onConfirmClickListener() {
				// showNotification();
				// // 显示下载对话框
				showDownloadDialog();
			}

			@Override
			public void onCancelClickListener() {

			}
		});
		dialog.show();
	}

	private NotificationManager mNotificationManager;
	private Notification mNotification;
	public static final int NOTIFY_ID = 0x49;// 十进制的73

	private void showNotification() {
		mNotification = new Notification(R.drawable.ic_launcher, "开始下载",
				System.currentTimeMillis());
		RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
				R.layout.download_notification_layout);
		contentView.setTextViewText(R.id.fileName, "huiyin_wap_2.1.zip");
		// 指定个性化视图
		mNotification.contentView = contentView;
		// 放置在"正在运行"栏目中
		mNotification.flags = Notification.FLAG_ONGOING_EVENT;
		mNotificationManager = (NotificationManager) mContext
				.getSystemService(Context.NOTIFICATION_SERVICE);
		mNotificationManager.notify(NOTIFY_ID, mNotification);

		// 现在文件
		downloadZip();
	}

	/**
	 * 显示软件下载对话框
	 */
	private void showDownloadDialog() {
		// 构造软件下载对话框
		downloadProgress = new DownloadDialog(mContext);
		downloadProgress.setTitle("下载更新");
		mProgress = downloadProgress.getProgressBar();
		tv_pro = downloadProgress.getMessage();

		downloadProgress.setMyClickListener(new MyCancelClickListener() {
			public void onCancelClickListener() {
				//目前不让取消
				//cancelUpdate = true;
			}
		});
		downloadProgress.show();

		// 现在文件
		downloadZip();
	}

	/**
	 * 下载apk文件
	 */
	private void downloadZip() {
		// 启动新线程下载软件
		new downloadZipThread().start();
	}

	/**
	 * 下载文件线程
	 * 
	 * @author coolszy
	 * @date 2012-4-26
	 * @blog http://blog.92coding.com
	 */
	private class downloadZipThread extends Thread {
		@Override
		public void run() {
			try {
				// 判断SD卡是否存在，并且是否具有读写权限
				if (Environment.getExternalStorageState().equals(
						Environment.MEDIA_MOUNTED)) {
					// 获得存储卡的路径
					basePath = Environment.getExternalStorageDirectory() + "/";
					mSavePath = basePath + "download";
					URL url = new URL(downUrl);
					// 创建连接
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					conn.connect();
					// 获取文件大小
					int length = conn.getContentLength();
					// 创建输入流
					InputStream is = conn.getInputStream();

					File file = new File(mSavePath);
					// 判断文件目录是否存在
					if (!file.exists()) {
						file.mkdir();
					}

					File zipFile = new File(mSavePath, mFileName);
					FileOutputStream fos = new FileOutputStream(zipFile);
					int count = 0;
					int sumNumread = 0;
					// 缓存
					byte buf[] = new byte[1024];
					// 写入到文件中
					do {
						int numread = is.read(buf);
						count += numread;
						sumNumread += numread;
						// 计算进度条位置
						progress = (int) (((float) count / length) * 100);

						if (((float) sumNumread / length) * 100 >= 5) {
							sumNumread = 0;
							Message msg = new Message();
							msg.obj = progress + "%";
							msg.what = DOWNLOAD;
							// 更新进度
							mHandler.sendMessage(msg);
						}

						if (numread <= 0) {
							// 下载完成
							mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
							break;
						}
						// 写入文件
						fos.write(buf, 0, numread);
					} while (!cancelUpdate);// 点击取消就停止下载.
					fos.close();
					is.close();
				} else {
					mHandler.sendEmptyMessage(DOWNLOAD_FAIL);
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
				mHandler.sendEmptyMessage(DOWNLOAD_FAIL);
			} catch (IOException e) {
				e.printStackTrace();
				mHandler.sendEmptyMessage(DOWNLOAD_FAIL);
			}

		}
	};

	private class EctractTherad extends Thread {
		@Override
		public void run() {
			super.run();

			// 删除www文件夹
			DeleteFile(new File(basePath + "huiyinlehu/www"));
			// 解压zip文件
			Ectract(mSavePath + File.separator + mFileName, basePath
					+ "huiyinlehu/");
			// 解压完成
			mHandler.sendEmptyMessage(Ectract_FINISH);
		}
	}

	/**
	 * 递归删除文件和文件夹
	 * 
	 * @param file
	 *            要删除的根目录
	 */
	public void DeleteFile(File file) {
		Log.d(TAG, "DeleteFile");
		if (file.exists() == false) {
			return;
		} else {
			if (file.isFile()) {
				file.delete();
				return;
			}
			if (file.isDirectory()) {
				File[] childFile = file.listFiles();
				if (childFile == null || childFile.length == 0) {
					file.delete();
					return;
				}
				for (File f : childFile) {
					DeleteFile(f);
				}
				file.delete();
			}
		}
	}

	/**
	 * 解压缩
	 * 
	 * @param sZipPathFile
	 *            要解压的文件
	 * @param sDestPath
	 *            解压到某文件夹
	 * @return
	 */
	public ArrayList<String> Ectract(String sZipPathFile, String sDestPath) {

		LogUtil.d(TAG, "Ectract : sZipPathFile = " + sZipPathFile);
		LogUtil.d(TAG, "Ectract : sDestPath    = " + sDestPath);

		ArrayList<String> allFileName = new ArrayList<String>();
		try {
			// 先指定压缩档的位置和档名，建立FileInputStream对象
			FileInputStream fins = new FileInputStream(sZipPathFile);
			// 将fins传入ZipInputStream中
			ZipInputStream zins = new ZipInputStream(fins);
			ZipEntry ze = null;
			byte[] ch = new byte[256];
			while ((ze = zins.getNextEntry()) != null) {
				File zfile = new File(sDestPath + ze.getName());
				File fpath = new File(zfile.getParentFile().getPath());
				LogUtil.d(TAG, "Ectract : zfile = " + zfile.getPath()
						+ "  fpath = " + fpath.getPath());
				if (ze.isDirectory()) {
					if (!zfile.exists())
						zfile.mkdirs();
					zins.closeEntry();
				} else {
					if (!fpath.exists())
						fpath.mkdirs();
					FileOutputStream fouts = new FileOutputStream(zfile);
					int i;
					allFileName.add(zfile.getAbsolutePath());
					while ((i = zins.read(ch)) != -1)
						fouts.write(ch, 0, i);
					zins.closeEntry();
					fouts.close();
				}
			}
			fins.close();
			zins.close();
		} catch (Exception e) {
			Log.d(TAG, "Extract error:" + e.getMessage());
			// 解压失败
			mHandler.sendEmptyMessage(Ectract_FAIL);
		}
		return allFileName;
	}

}